/***************************************************************************
 *   This is a part of the NextCAD Web APP.                                *
 *   Copyright (C) AMCAX, All rights reserved.                             *
 ***************************************************************************/

import { pickedFaceData, pickedVertexData } from '@amcax/base';
import {
  NumberInputFormat,
  PickInputRJSFFormat,
} from '@app-cad/common/components/command-form/constants';
import { NonDialogPickableCommandForm } from '@app-cad/common/components/command-form/pickable';
import { useCommand } from '@app-cad/common/hooks/useCommand';
import { useTools } from '@app-cad/common/hooks/useTools';
import { RJSFSchema } from '@rjsf/utils';
import { useAsyncEffect } from 'ahooks';
import { isEmpty } from 'lodash';
import { useEffect, useState } from 'react';
import { ChildPlaneCommandProps } from './types';

type FormDataType = {
  center: pickedVertexData;
  radius: number;
  plane: pickedFaceData;
  startAngle: number;
  endAngle: number;
};

export function CenterRadius({
  props,
  onClose,
  editDxid,
}: ChildPlaneCommandProps) {
  const [formData, setFormData] = useState<FormDataType>({
    center: undefined,
    radius: 20,
    plane: undefined,
    startAngle: 0,
    endAngle: 180,
  });

  const { picker } = useTools();

  useEffect(() => {
    preview();
  }, [formData]);

  const checkAndFinishDraw = async () => {
    const { center, radius, plane, startAngle, endAngle } = formData;
    if (
      isEmpty(center) ||
      isEmpty(plane) ||
      radius == null ||
      radius === 0 ||
      (startAngle === 0 && endAngle === 0)
    )
      return;

    await executeData(false);

    onClose();
  };

  const { initEditDependency, initingEdit, confirmCommand, clear, isLoading } =
    useCommand('cmd-offset-curved', {
      commandName: 'CreateCurve',
      editDxid: props?.shape,
      onClose,
      finishDraw: checkAndFinishDraw,
    });

  useAsyncEffect(async () => {
    if (props) {
      const center = props?.params?.center;
      const radius = props?.params?.radius;
      const plane = props?.params?.plane;

      await initEditDependency([center, plane]);

      const defaultCenter = center
        ? (picker.generatePickObjByPickID(center) as pickedVertexData)
        : undefined;
      const defaultPlane = plane
        ? (picker.generatePickObjByPickID(plane) as pickedFaceData)
        : undefined;
      const startAngle = props?.params?.startAngle;
      const endAngle = props?.params?.endAngle;
      setFormData({
        center: defaultCenter,
        radius: radius,
        plane: defaultPlane,
        startAngle: startAngle,
        endAngle: endAngle,
      });
    }
  }, [editDxid]);

  const executeData = async (preview: boolean = false) => {
    const { center, radius, plane, startAngle, endAngle } = formData;
    const planeId = plane?.meshId;
    let minAngle = startAngle;
    let maxAngle = endAngle;
    if (typeof minAngle === 'number' && typeof maxAngle === 'number') {
      minAngle = startAngle > endAngle ? endAngle : startAngle;
      maxAngle = startAngle > endAngle ? startAngle : endAngle;
    }

    await confirmCommand(
      {
        type: 'ArcOfCircle',
        a: {
          mode: 'center-radius',
          center: center.vertexId,
          radius: radius,
          plane: planeId,
          startAngle: minAngle,
          endAngle: maxAngle,
        },
      },
      preview,
    );
  };

  const isFormDataValid = () => {
    const { center, radius, plane, startAngle, endAngle } = formData;
    return (
      center != null &&
      radius != null &&
      plane != null &&
      startAngle != null &&
      endAngle != null
    );
  };

  const preview = async () => {
    const { center, radius, plane, startAngle, endAngle } = formData;
    if (
      isEmpty(center) ||
      isEmpty(plane) ||
      radius == null ||
      radius === 0 ||
      (startAngle === 0 && endAngle === 0)
    ) {
      clear();
      return;
    }

    await executeData(true);
  };

  const schema: RJSFSchema = {
    type: 'object',
    properties: {
      center: {
        type: 'string',
        format: PickInputRJSFFormat.PickVertex,
      },
      radius: {
        type: 'number',
        title: '半径',
        format: NumberInputFormat.Length,
      },
      plane: {
        type: 'string',
        format: PickInputRJSFFormat.PickPlane,
      },
      startAngle: {
        type: 'number',
        title: '起始角度',
        format: NumberInputFormat.Angle,
      },
      endAngle: {
        type: 'number',
        title: '结束角度',
        format: NumberInputFormat.Angle,
      },
    },
  };

  const extraUiSchema = {
    center: {
      'ui:placeholder': '请输入圆心',
      'ui:autofocus': true,
    },
    radius: {
      'ui:placeholder': '请输入半径',
    },
    plane: {
      'ui:placeholder': '请输入支持面',
    },
    startAngle: {
      'ui:placeholder': '请输入起始角度',
    },
    endAngle: {
      'ui:placeholder': '请输入结束角度',
    },
  };

  return (
    <NonDialogPickableCommandForm
      disabled={initingEdit}
      className='-mt-3'
      submitLoading={isLoading}
      isFormDataValid={isFormDataValid()}
      onCancel={onClose}
      schema={schema}
      formData={formData}
      onChange={(v) => {
        const data = {
          center: v.center,
          radius: v.radius,
          plane: v.plane,
          startAngle: v.startAngle,
          endAngle: v.endAngle,
        };
        setFormData(data);
      }}
      extraUiSchema={extraUiSchema}
      submitText='完成'
      onSubmit={checkAndFinishDraw}
    />
  );
}
